Clojure 是一種動態的、強類型、執行在 Java 虛擬機(JVM)上的 Lisp 方言。目前算是函數式編程(functional programming)領域內一個挺熱門的語言選擇。這個系列的目的是通過介紹 Clojure 高表達力的語言風格、先進的庫(library)、及無縫使用 Java/JVM 生態系豐富的類庫來展示 Clojure 在大數據領域的優勢。
在《Programming Clojure》簡體中文翻譯的譯序中,作者提到了 Java code 跟 Clojure code 的差別。關於原問題請見淘宝面试题:如何充分利用多核CPU,计算很大的List中所有整数的和,而 Clojure code 則在這篇回文中被提出几行代码解决淘宝面试题之 Clojure 版,解答程式碼長的如下:
(defn mysum2 [coll n]
(let [sub-colls (partition n n [0] coll)
result-coll (map #(future (reduce + 0 %)) sub-colls)]
(reduce #(+ %1 @%2) 0 result-coll)))
使用了 map / reduce 以及併發函數,輕易的把這題解決!這就是 Clojure。
$PATH
。lein help
就會開始下載 Clojure 的 jar 檔案及其他必要基礎檔案了!Leiningen,簡稱 Lein,是一個用以管理 Clojure 套件版本的程式。對應的 Java 工具是 Maven。如果專案中有用到 Java 的函式庫,也可以使用 Lein 來管理!
lein new <project name> <template name>
:專案起手式。template name 非必須,不過有人會把特定類型軟體的專案結構及必要庫包裝成專案檔,例如用來寫 web app 的 ring 或者一些資料庫軟體應用。
project.clj
,裡面有依賴的庫、編譯參數設定、專案 metadata 等。project.clj
中的庫,是沒辦法 include 的喔!這點跟 Javascript 有像。lein deps
來更新專案所依賴的 Clojure 及庫。注意:Clojure 其實不是一個安裝檔,而是一個 Java 程式及一大堆 Java class!所以,每次建立專案後,可以選擇合適的 Clojure,例如穩定的 1.6、1.7 或者是 beta 中的版本號。lein repl
會開啟一個本專案專屬的 REPL,可以從該 REPL 中快速存取 src
資料夾中的程式碼及函式庫。lein run
如果有寫好編譯方式,會通過此程式將專案執行起來。例如,專案是 web app 則會啟動 server。提示各章節重點,接下來各章也是以提示加重點筆記為主,不做書摘。
(defn func-name [argv] (body))
map
及 reduce
函數(#(func % ...) argv)
let
如何通過它建立局部變量環境recur
的語法:用遞迴的寫法寫出能被傳換為讓 JVM 以迴圈執行的 bytecode。car
/cdr
:take
, drop
filter
、take-while
及 drop-while
into
、conj
apply
、partial
函數可以根據參數種類選定不同的函數實體進行運算。最初步的用途就是可以大幅單純化函數結構,而不用輸入一個 list 再判斷數量,套用到複雜的 if
結構中。
(defn multi-arity
([f-arg s-arg t-arg] (do-thing f-arg s-arg t-arg))
([f-arg s-arg] (do-thing f-arg s-arg))
([f-arg] (do-thing f-arg)))
Clojure 的正則是直接呼叫 Java 的核心函式庫。
(defn matching-part
[part]
{:name (clojure.string/replace (:name part) #"^left-" "right-")
:size (:size part)})
(matching-part {:name "left-eye" :size 1})
; => {:name "right-eye" :size 1}
take-while
可以用來做複雜的遍歷、篩選器。或者直接使用
(take-while #(< (:month %) 4)
(drop-while #(< (:month %) 2) food-journal))